//---------------------------------------------------------------------------------
// Copyright (c) 2008 VoiceLynx Project
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
//     1. The origin of this software must not be misrepresented; you must not
//        claim that you wrote the original software. If you use this software
//        in a product, an acknowledgment in the product documentation would be
//        appreciated but is not required.
//
//     2. Altered source versions must be plainly marked as such, and must not be
//        misrepresented as being the original software.
//
//     3. This notice may not be removed or altered from any source
//        distribution.
//---------------------------------------------------------------------------------

#include "VLPackets.h"

#include "VLUser.h"

#define VL_READ_IN_DATA_STREAM(ds, var)          ds.readData(#var, &var)
#define VL_READ_IN_DATA_STREAM_ENUM(ds, var)     ds.readData(#var, (int*) &var)
#define VL_READ_IN_DATA_STREAM_BYTES(ds, var)    ds.readData(#var, *var.get())

#define VL_WRITE_OUT_DATA_STREAM(ds, var)        ds.writeData(#var, var)
#define VL_WRITE_OUT_DATA_STREAM_ENUM(ds, var)   ds.writeData(#var, (int) var)
#define VL_WRITE_OUT_DATA_STREAM_BYTES(ds, var)  ds.writeData(#var, *var.get())

const char *VL_PACKET_TYPE_DS_NAME = "PacketType";

//
// VLBasePacket
//
VLBasePacket::VLBasePacket(VLEPacketType packetType)
: mPacketType(packetType)
{
  
}

VLBasePacket::VLBasePacket(InDataStream &ds)
{
  ds.readData(VL_PACKET_TYPE_DS_NAME, (int*) &mPacketType);
}

void VLBasePacket::serialize(OutDataStream &ds)
{
  ds.writeData(VL_PACKET_TYPE_DS_NAME, (int) mPacketType);
}

//
// VLAuthenticationPacket
//
VLAuthenticationPacket::VLAuthenticationPacket(const VLString &nameParam, 
                                               const VLString &passwordParam)
: VLBasePacket(VL_PT_AUTHENTICATION),
  name(nameParam),
  password(passwordParam)
{

}

VLAuthenticationPacket::VLAuthenticationPacket(InDataStream &ds)
: VLBasePacket(ds)
{
  VL_READ_IN_DATA_STREAM(ds, name);
  VL_READ_IN_DATA_STREAM(ds, password);

}

void VLAuthenticationPacket::serialize(OutDataStream &ds)
{
  VLBasePacket::serialize(ds);
  VL_WRITE_OUT_DATA_STREAM(ds, name);
  VL_WRITE_OUT_DATA_STREAM(ds, password);
}

//
// VLAuthenticationResponsePacket
//
VLAuthenticationResponsePacket::VLAuthenticationResponsePacket(bool successfulParam, VLUserId userIdParam)
: VLBasePacket(VL_PT_AUTHENTICATION_RESPONSE),
  successful(successfulParam),
  userId(userIdParam)
{

}

VLAuthenticationResponsePacket::VLAuthenticationResponsePacket(InDataStream &ds)
: VLBasePacket(ds)
{
  VL_READ_IN_DATA_STREAM(ds, successful);
  VL_READ_IN_DATA_STREAM(ds, userId);
}

void VLAuthenticationResponsePacket::serialize(OutDataStream &ds)
{
  VLBasePacket::serialize(ds);
  VL_WRITE_OUT_DATA_STREAM(ds, successful);
  VL_WRITE_OUT_DATA_STREAM(ds, userId);
}

//
// VLUserPacket
//
VLUserPacket::VLUserPacket(VLEPacketType packetType, VLUserId userIdParam)
: VLBasePacket(packetType),
  userId(userIdParam)
{

}

VLUserPacket::VLUserPacket( InDataStream &ds )
: VLBasePacket(ds)
{
  VL_READ_IN_DATA_STREAM(ds, userId);
}

void VLUserPacket::serialize( OutDataStream &ds )
{
  VLBasePacket::serialize(ds);
  VL_WRITE_OUT_DATA_STREAM(ds, userId);
}

//
// VLUserJoinedPacket
//
VLUserJoinedPacket::VLUserJoinedPacket(VLUser &user)
: VLUserPacket(VL_PT_USER_JOINED, user.userId),
  userName(user.userName),
  isAuthenticated(user.isAuthenticated),
  connectTime(user.connectTime)
{
  
}

VLUserJoinedPacket::VLUserJoinedPacket( InDataStream &ds )
: VLUserPacket(ds)
{
  VL_READ_IN_DATA_STREAM(ds, userName);
  VL_READ_IN_DATA_STREAM(ds, isAuthenticated);
  VL_READ_IN_DATA_STREAM(ds, connectTime);
}

void VLUserJoinedPacket::serialize(OutDataStream &ds)
{
  VLUserPacket::serialize(ds);
  VL_WRITE_OUT_DATA_STREAM(ds, userName);
  VL_WRITE_OUT_DATA_STREAM(ds, isAuthenticated);
  VL_WRITE_OUT_DATA_STREAM(ds, connectTime);
}

void VLUserJoinedPacket::applyToUser(VLUser &user)
{
  user.userId = userId;
  user.userName = userName;
  user.isAuthenticated = isAuthenticated;
  user.connectTime = connectTime;
}

//
// VLUserLeftPacket
//
VLUserLeftPacket::VLUserLeftPacket(VLUserId userId)
: VLUserPacket(VL_PT_USER_LEFT, userId)
{

}

VLUserLeftPacket::VLUserLeftPacket(InDataStream &ds)
: VLUserPacket(ds)
{

}

void VLUserLeftPacket::serialize(OutDataStream &ds)
{
  VLUserPacket::serialize(ds);
}

//
// VLUserChangedPacket
//
VLUserChangedChannelPacket::VLUserChangedChannelPacket(VLUserId userId)
: VLUserPacket(VL_PT_USER_CHANGED_CHANNEL, userId)
{

}

VLUserChangedChannelPacket::VLUserChangedChannelPacket(InDataStream &ds)
: VLUserPacket(ds)
{
  
}

void VLUserChangedChannelPacket::serialize(OutDataStream &ds)
{
  VLUserPacket::serialize(ds);
}

//
// VLVoiceDataPacket
//
VLVoiceDataPacket::VLVoiceDataPacket(VLUserId userId, VLU8 codecChannelHash, VLByteArrayPtr voiceData)
: VLUserPacket(VL_PT_VOICEDATA, userId),
  mCodecChannelHash(codecChannelHash),
  mVoiceData(voiceData)
{
  
}

VLVoiceDataPacket::VLVoiceDataPacket(InDataStream &ds)
: VLUserPacket(ds),
  mVoiceData(new VLByteArray())
{
  VL_READ_IN_DATA_STREAM(ds, mCodecChannelHash);
  VL_READ_IN_DATA_STREAM_BYTES(ds, mVoiceData);
}

void VLVoiceDataPacket::serialize(OutDataStream &ds)
{
  VLUserPacket::serialize(ds);
  VL_WRITE_OUT_DATA_STREAM(ds, mCodecChannelHash);
  VL_WRITE_OUT_DATA_STREAM_BYTES(ds, mVoiceData);
}
